package dongchel.vrp.ais;

import java.util.ArrayList;
import java.util.List;

import dongchel.vrp.entity.MultiObjectiveObject;
import dongchel.vrp.general.CompareObject;

public class MemorySpace {
	private MultiObjectiveObject maxSolutionSpace;
	private MultiObjectiveObject minSolutionSpace;
	private int cellNumer = 10;
	
	private List<CompareObject> secondaryPopulation = new ArrayList<CompareObject>();
	
	private List<Cell> cellList;

	private Cell densityCell;
	
	public List<Cell> getCellList() {
		return cellList;
	}

	public void setCellList(List<Cell> cellList) {
		this.cellList = cellList;
	}

	public Cell getDensityCell() {
		return densityCell;
	}

	public void setDensityCell(Cell densityCell) {
		this.densityCell = densityCell;
	}

	public MemorySpace(List<CompareObject> secondaryPopulation){
		this.secondaryPopulation = secondaryPopulation;		
		refresh();	
	}
	
	public void refresh(){
		int m = 0;
		if(cellList == null){
			cellList = new ArrayList<Cell>(); 
		}else{
			cellList.clear();
		}
		
		if(secondaryPopulation.size()>0){
			maxSolutionSpace = secondaryPopulation.get(0).getValue();
			minSolutionSpace = secondaryPopulation.get(0).getValue();
			
			for(int i=1;i<secondaryPopulation.size();i++){
				MultiObjectiveObject mo = secondaryPopulation.get(i).getValue();
				
				maxSolutionSpace = mergeMax(maxSolutionSpace, mo);
				minSolutionSpace = mergeMin(minSolutionSpace, mo);
			}
			
			for(int i=0;i<secondaryPopulation.size();i++){
				MultiObjectiveObject mo = secondaryPopulation.get(i).getValue();
				boolean isContained = false;
				for(int j=0;j<cellList.size();j++){
					Cell currentCell = cellList.get(j);
					if(currentCell.checkIsContained(mo)){
						currentCell.addSize();
						isContained = true;
						break;
					}
				}
				
				if(!isContained){
					Cell c = new Cell(mo, this);		
					cellList.add(c);
				}
			}
			densityCell = null;
			for(int i=0;i<cellList.size();i++){
				Cell currentCell = cellList.get(i);
				if(densityCell == null){
					densityCell = currentCell;
				}else{
					if(currentCell.getSize()>densityCell.getSize()){
						densityCell = currentCell;
					}
				}
			}
			
			
		}
		
	}
	
	public void refresh(List<CompareObject> secondaryPoList){
		this.secondaryPopulation = secondaryPopulation;
		refresh();
	}
	
	public double getAverageDensity(){
		double aveDensity = 0;
		for(int i=0;i<cellList.size();i++){
			aveDensity += cellList.get(i).getSize();
		}
		
		aveDensity = aveDensity/cellList.size();
		
		return aveDensity;
	}
	
	public Cell checkCell(MultiObjectiveObject mo){
		for(int i=0;i<cellList.size();i++){
			if(cellList.get(i).checkIsContained(mo)){
				return cellList.get(i);
			}
		}
		return null;
	}
	
	public List<CompareObject> getSecondaryPopulation() {
		return secondaryPopulation;
	}
	public void setSecondaryPopulation(List<CompareObject> secondaryPopulation) {
		this.secondaryPopulation = secondaryPopulation;
	}
	public MultiObjectiveObject getMaxSolutionSpace() {
		return maxSolutionSpace;
	}
	public void setMaxSolutionSpace(MultiObjectiveObject maxSolutionSpace) {
		this.maxSolutionSpace = maxSolutionSpace;
	}
	public MultiObjectiveObject getMinSolutionSpace() {
		return minSolutionSpace;
	}
	public void setMinSolutionSpace(MultiObjectiveObject minSolutionSpace) {
		this.minSolutionSpace = minSolutionSpace;
	}
	public int getCellNumer() {
		return cellNumer;
	}
	public void setCellNumer(int cellNumer) {
		this.cellNumer = cellNumer;
	}
	
	public MultiObjectiveObject mergeMax(MultiObjectiveObject mo1, MultiObjectiveObject mo2){
		MultiObjectiveObject mo = new MultiObjectiveObject();
		List l = new ArrayList();
		for(int i=0;i<mo1.getObjectiveList().size();i++){
			double d1 = (Double) mo1.getObjectiveList().get(i);
			double d2 = (Double) mo2.getObjectiveList().get(i);
			if(d1<d2){
				l.add(d2);
			}else{
				l.add(d1);
			}
		}
		mo.setObjectiveList(l);
		return mo;
	}
	public MultiObjectiveObject mergeMin(MultiObjectiveObject mo1, MultiObjectiveObject mo2){
		MultiObjectiveObject mo = new MultiObjectiveObject();
		List l = new ArrayList();
		for(int i=0;i<mo1.getObjectiveList().size();i++){
			double d1 = (Double) mo1.getObjectiveList().get(i);
			double d2 = (Double) mo2.getObjectiveList().get(i);
			if(d1>d2){
				l.add(d2);
			}else{
				l.add(d1);
			}
		}
		mo.setObjectiveList(l);
		return mo;
	}
/**
 * list
density
 */
}
